﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using RuleJudge.RuleData;
using System.IO;
using RuleJudge.Tools;
using RuleJudge.Judge;
using SLANCommon.Enum;
using SLANCommon;

namespace RuleJudge
{
    public abstract class BaseRuleJudge
    {
        bool _IsIndexData = false;

        protected List<MeltingPeak> _meltPeaks = new List<MeltingPeak>();
        protected List<Sample> _samples = new List<Sample>();
        protected List<Target> _targets = new List<Target>();
        protected List<Tube> _tubes = new List<Tube>();

        protected List<Paramter> _paramters = new List<Paramter>();

        /// <summary>
        /// 获取类型
        /// </summary>
        /// <returns></returns>
        protected abstract EProjectType GetType();

        /// <summary>
        /// 是否需要Index方式数据
        /// </summary>
        /// <returns></returns>
        public virtual bool NeedIndexData() { return true; }

        /// <summary>
        /// 验证，验证主程序和规则判断是否匹配
        /// </summary>
        /// <param name="version">主程序版本</param>
        /// <param name="projectType">项目类型</param>
        /// <param name="targets">项目目标集合</param>
        /// <param name="channels">通道号</param>
        /// <param name="tubes">管号</param>
        /// <returns>
        /// Null ：匹配
        /// Other：不匹配，返回对应错误信息
        /// </returns>
        public abstract string Validate(double version, EProjectType projectType, string[] targets, int[] channels, int[] tubes);

        /// <summary>
        /// 结论判断
        /// </summary>
        /// <param name="stream">
        /// 判断信息流
        /// 数据流结构：
        ///     Version：版本号，double
        ///     判断类型：int（AQ、Melt、HRM、AD、RQ等等。）
        ///     样本列表
        /// </param>
        /// <returns>
        /// Null ：判断正确
        /// Other：判断错误，返回对应错误信息        
        /// </returns>
        public virtual string Judge(Stream stream)
        {
            string str = null;

            RuleStream streamEx = new RuleStream();
            stream.Seek(0, SeekOrigin.Begin);
            stream.CopyTo(streamEx);
            streamEx.Seek(0, SeekOrigin.Begin);
            //判断版本
            double version = streamEx.ReadDouble();
            str = VersionValidate(version);
            if (!string.IsNullOrEmpty(str))
                return str;

            //转换数据
            ConvertStreamToSample(streamEx);

            return Judge();
        }

        protected virtual string VersionValidate(double version)
        {
            return null;
        }

        protected abstract string Judge();

        /// <summary>
        /// 获取判断结果
        /// </summary>
        /// <returns></returns>
        public virtual Stream GetResult()
        {
            RuleStream stream = new RuleStream();
            if(_IsIndexData)
            {
                #region Index传输
                RuleStream tmpStream = null;
                List<AdvRuleKey> tmpKeys = new List<AdvRuleKey>();
                List<byte[]> tmpDatas = new List<byte[]>();

                List<AdvRuleKey> keys = new List<AdvRuleKey>();
                List<byte[]> datas = new List<byte[]>();

                tmpStream = new RuleStream();
                //新增熔解峰
                foreach (Sample sample in _samples)
                {
                    foreach (Target target in sample.Targets)
                    {
                        foreach (MeltingPeak mp in target.Peaks)
                        {
                            if (_meltPeaks.Contains(mp) == false)
                                _meltPeaks.Add(mp);
                        }
                    }
                }
                tmpStream.Write(_meltPeaks.Count);
                foreach (MeltingPeak peak in _meltPeaks)
                {
                    tmpKeys.Clear();
                    tmpDatas.Clear();

                    tmpKeys.Add(AdvRuleKey.Key);
                    tmpDatas.Add(BytesConverter.GetBytes(peak.Key));
                    tmpKeys.Add(AdvRuleKey.IsUnKnown);
                    tmpDatas.Add(BytesConverter.GetBytes(peak.IsUnKnown));
                    tmpKeys.Add(AdvRuleKey.Tm);
                    tmpDatas.Add(BytesConverter.GetBytes(peak.Tm));
                    tmpKeys.Add(AdvRuleKey.Rm);
                    tmpDatas.Add(BytesConverter.GetBytes(peak.Rm));
                    tmpKeys.Add(AdvRuleKey.Width);
                    tmpDatas.Add(BytesConverter.GetBytes(peak.Width));
                    tmpKeys.Add(AdvRuleKey.YValue);
                    tmpDatas.Add(BytesConverter.GetBytes(peak.YValue));
                    tmpStream.WriteIndex(tmpKeys, tmpDatas);
                }
                keys.Add(AdvRuleKey.MeltPeaks);
                datas.Add(tmpStream.ToArray());
                tmpStream.Close();

                tmpStream = new RuleStream();
                tmpStream.Write(_targets.Count);
                foreach (Target target in _targets)
                {
                    tmpKeys.Clear();
                    tmpDatas.Clear();

                    tmpKeys.Add(AdvRuleKey.Key);
                    tmpDatas.Add(BytesConverter.GetBytes(target.Key));
                    tmpKeys.Add(AdvRuleKey.Conclusions);
                    tmpDatas.Add(GetConclusionData(target.Conclusion));
                    tmpKeys.Add(AdvRuleKey.CustomResults);
                    tmpDatas.Add(GetCustomResultData(target.CustomResults));

                    //Ct
                    tmpKeys.Add(AdvRuleKey.Ct);
                    tmpDatas.Add(BytesConverter.GetBytes(target.Result.Ct));
                    tmpKeys.Add(AdvRuleKey.CtMean);
                    tmpDatas.Add(BytesConverter.GetBytes(target.Result.CtMean));
                    tmpKeys.Add(AdvRuleKey.CtSD);
                    tmpDatas.Add(BytesConverter.GetBytes(target.Result.CtSD));
                    tmpKeys.Add(AdvRuleKey.CtCV);
                    tmpDatas.Add(BytesConverter.GetBytes(target.Result.CtCV));
                    //Cn
                    tmpKeys.Add(AdvRuleKey.Cn);
                    tmpDatas.Add(BytesConverter.GetBytes(target.Result.Cn));
                    tmpKeys.Add(AdvRuleKey.CnMean);
                    tmpDatas.Add(BytesConverter.GetBytes(target.Result.CnMean));
                    tmpKeys.Add(AdvRuleKey.CnSD);
                    tmpDatas.Add(BytesConverter.GetBytes(target.Result.CnSD));
                    tmpKeys.Add(AdvRuleKey.CnCV);
                    tmpDatas.Add(BytesConverter.GetBytes(target.Result.CnCV));
                    //Rn
                    tmpKeys.Add(AdvRuleKey.Rn);
                    tmpDatas.Add(BytesConverter.GetBytes(target.Result.Rn));

                    //熔解峰
                    if (target.Peaks.Count > 0)
                    {
                        RuleStream stream1 = new RuleStream();
                        stream1.Write(BytesConverter.GetBytes(target.Peaks.Count));
                        foreach (MeltingPeak Peak in target.Peaks)
                        {
                            stream1.Write(BytesConverter.GetBytes(_meltPeaks.IndexOf(Peak)));
                        }

                        tmpKeys.Add(AdvRuleKey.MeltPeaks);
                        tmpDatas.Add(stream1.ToArray());
                        stream1.Close();
                    }

                    //增加曲线数据
                    if (target.Result.RawCurve != null && target.Result.RawCurve.Count > 0)
                    {
                        tmpKeys.Add(AdvRuleKey.RawCurve);
                        tmpDatas.Add(GetByte(target.Result.RawCurve));
                    }
                    if (target.Result.AMPCurve != null && target.Result.AMPCurve.Count > 0)
                    {
                        tmpKeys.Add(AdvRuleKey.AMPCurve);
                        tmpDatas.Add(GetByte(target.Result.AMPCurve));
                    }
                    if (target.Result.RawMeltingCurve != null && target.Result.RawMeltingCurve.Count > 0)
                    {
                        tmpKeys.Add(AdvRuleKey.RawMeltingCurve);
                        tmpDatas.Add(GetByte(target.Result.RawMeltingCurve));
                    }
                    if (target.Result.PeakCurve != null && target.Result.PeakCurve.Count > 0)
                    {
                        tmpKeys.Add(AdvRuleKey.PeakCurve);
                        tmpDatas.Add(GetByte(target.Result.PeakCurve));
                    }
                    if (target.Result.NormalizationPeakCurve != null && target.Result.NormalizationPeakCurve.Count > 0)
                    {
                        tmpKeys.Add(AdvRuleKey.NormalizationPeakCurve);
                        tmpDatas.Add(GetByte(target.Result.NormalizationPeakCurve));
                    }
                    if (target.Result.DerivativeCurve != null && target.Result.DerivativeCurve.Count > 0)
                    {
                        tmpKeys.Add(AdvRuleKey.DerivativeCurve);
                        tmpDatas.Add(GetByte(target.Result.DerivativeCurve));
                    }
                    if (target.Result.NormalizationCurve != null && target.Result.NormalizationCurve.Count > 0)
                    {
                        tmpKeys.Add(AdvRuleKey.NormalizationCurve);
                        tmpDatas.Add(GetByte(target.Result.NormalizationCurve));
                    }
                    if (target.Result.ShiftCurve != null && target.Result.ShiftCurve.Count > 0)
                    {
                        tmpKeys.Add(AdvRuleKey.ShiftCurve);
                        tmpDatas.Add(GetByte(target.Result.ShiftCurve));
                    }
                    if (target.Result.DifferenceCurve != null && target.Result.DifferenceCurve.Count > 0)
                    {
                        tmpKeys.Add(AdvRuleKey.DifferenceCurve);
                        tmpDatas.Add(GetByte(target.Result.DifferenceCurve));
                    }

                    tmpStream.WriteIndex(tmpKeys, tmpDatas);
                }
                keys.Add(AdvRuleKey.Targets);
                datas.Add(tmpStream.ToArray());
                tmpStream.Close();

                tmpStream = new RuleStream();
                tmpStream.Write(_tubes.Count);
                foreach (Tube tube in _tubes)
                {
                    tmpKeys.Clear();
                    tmpDatas.Clear();

                    tmpKeys.Add(AdvRuleKey.Key);
                    tmpDatas.Add(BytesConverter.GetBytes(tube.Key));
                    tmpKeys.Add(AdvRuleKey.Conclusions);
                    tmpDatas.Add(GetConclusionData(tube.Conclusion));
                    tmpKeys.Add(AdvRuleKey.CustomResults);
                    tmpDatas.Add(GetCustomResultData(tube.CustomResults));

                    tmpStream.WriteIndex(tmpKeys, tmpDatas);
                }
                keys.Add(AdvRuleKey.Wells);
                datas.Add(tmpStream.ToArray());
                tmpStream.Close();

                tmpStream = new RuleStream();
                tmpStream.Write(_samples.Count);
                foreach (Sample sample in _samples)
                {
                    tmpKeys.Clear();
                    tmpDatas.Clear();

                    tmpKeys.Add(AdvRuleKey.Key);
                    tmpDatas.Add(BytesConverter.GetBytes(sample.Key));
                    tmpKeys.Add(AdvRuleKey.Conclusions);
                    tmpDatas.Add(GetConclusionData(sample.Conclusion));
                    tmpKeys.Add(AdvRuleKey.CustomResults);
                    tmpDatas.Add(GetCustomResultData(sample.CustomResults));

                    tmpStream.WriteIndex(tmpKeys, tmpDatas);
                }
                keys.Add(AdvRuleKey.Samples);
                datas.Add(tmpStream.ToArray());
                tmpStream.Close();
           
                stream.Write(AdvRuleKey.Index);
                stream.WriteIndex(keys, datas);
                #endregion
            }
            else
            {
                #region 旧逻辑
                foreach (Sample sample in _samples)
                {
                    stream.Write((int)AdvRuleKey.Sample);
                    stream.Write(sample.Key);

                    WriteConclusionToStream(sample.Conclusion, stream);
                    WriteCustomResultToStream(sample.CustomResults, stream);

                    stream.Write((int)AdvRuleKey.End);
                }

                foreach (Tube tube in _tubes)
                {
                    stream.Write((int)AdvRuleKey.Well);
                    stream.Write(tube.Key);

                    WriteConclusionToStream(tube.Conclusion, stream);
                    WriteCustomResultToStream(tube.CustomResults, stream);

                    stream.Write((int)AdvRuleKey.End);
                }
                foreach (Target target in _targets)
                {
                    stream.Write((int)AdvRuleKey.Target);
                    stream.Write(target.Key);

                    WriteConclusionToStream(target.Conclusion, stream);
                    WriteCustomResultToStream(target.CustomResults, stream);

                    stream.Write((int)AdvRuleKey.End);
                }
                foreach (MeltingPeak peak in _meltPeaks)
                {
                    stream.Write((int)AdvRuleKey.MeltPeak);
                    stream.Write(peak.Key);

                    stream.Write((int)AdvRuleKey.IsUnKnown);
                    stream.Write(peak.IsUnKnown);

                    stream.Write((int)AdvRuleKey.End);
                }
                #endregion
            }
            return stream;
        }

        #region protected函数
        #region 旧逻辑，适应旧版本
        protected void WriteConclusionToStream(List<Conclusion> conclusions, RuleStream stream)
        {
            if (conclusions.Count > 0)
            {
                stream.Write((int)AdvRuleKey.Conclusions);
                stream.Write(conclusions.Count);

                foreach (Conclusion conclusion in conclusions)
                {
                    stream.Write((int)AdvRuleKey.Conclusion);
                    stream.Write((int)AdvRuleKey.Content);
                    stream.Write(conclusion.Content);
                    stream.Write((int)AdvRuleKey.Color);
                    stream.Write(conclusion.Color.ToString());

                    stream.Write((int)AdvRuleKey.End);
                }
                stream.Write((int)AdvRuleKey.End);
            }
        }

        protected void WriteCustomResultToStream(List<CustomResult> customResults, RuleStream stream)
        {
            if (customResults.Count > 0)
            {
                stream.Write((int)AdvRuleKey.CustomResults);
                stream.Write(customResults.Count);

                foreach (CustomResult customResult in customResults)
                {
                    stream.Write((int)AdvRuleKey.CustomResult);
                    stream.Write((int)AdvRuleKey.Name);
                    stream.Write(customResult.Name);
                    stream.Write((int)AdvRuleKey.Value);
                    stream.Write(customResult.Value);
                    stream.Write((int)AdvRuleKey.DecimalDigits);
                    stream.Write(customResult.DecimalDigits);
                    //旧逻辑，不需要对应Content

                    stream.Write((int)AdvRuleKey.End);
                }
                stream.Write((int)AdvRuleKey.End);
            }
        }
        #endregion
        protected byte[] GetConclusionData(List<Conclusion> conclusions)
        {
            byte[] retByte = null;
            List<AdvRuleKey> keys = new List<AdvRuleKey>();
            List<byte[]> datas = new List<byte[]>();

            RuleStream stream = new RuleStream();
            stream.Write(conclusions.Count);
            foreach (Conclusion conclusion in conclusions)
            {
                keys.Add(AdvRuleKey.Content);
                datas.Add(BytesConverter.GetBytes(conclusion.Content));
                keys.Add(AdvRuleKey.Color);
                datas.Add(BytesConverter.GetBytes(conclusion.Color.ToString()));

                stream.WriteIndex(keys, datas);
                keys.Clear();
                datas.Clear();
            }
            retByte = stream.ToArray();
            stream.Close();
            return retByte;
        }
        protected byte[] GetCustomResultData(List<CustomResult> customResults)
        {
            byte[] retByte = null;
            List<AdvRuleKey> keys = new List<AdvRuleKey>();
            List<byte[]> datas = new List<byte[]>();

            RuleStream stream = new RuleStream();
            stream.Write(customResults.Count);
            foreach (CustomResult customResult in customResults)
            {
                keys.Add(AdvRuleKey.Name);
                datas.Add(BytesConverter.GetBytes(customResult.Name));
                if (!string.IsNullOrEmpty(customResult.Content))
                {
                    keys.Add(AdvRuleKey.Content);
                    datas.Add(BytesConverter.GetBytes(customResult.Content));
                }
                else
                {
                    keys.Add(AdvRuleKey.Value);
                    datas.Add(BytesConverter.GetBytes(customResult.Value));
                    keys.Add(AdvRuleKey.DecimalDigits);
                    datas.Add(BytesConverter.GetBytes(customResult.DecimalDigits));
                }
                stream.WriteIndex(keys, datas);
                keys.Clear();
                datas.Clear();
            }
            retByte = stream.ToArray();
            stream.Close();
            return retByte;
        }

        protected bool ConvertStreamToSample(RuleStream stream)
        {
            _samples.Clear();
            _targets.Clear();
            _tubes.Clear();
            _meltPeaks.Clear();

            AdvRuleKey key = stream.ReadKey();
            if (key == AdvRuleKey.Index)
            {
                _IsIndexData = true;
                #region Index传输
                List<AdvRuleKey> tmpKeys;
                List<byte[]> tmpDatas;
                RuleStream tmpStream = null;

                List<AdvRuleKey> keys;
                List<byte[]> datas;

                stream.ReadIndex(out keys, out datas);
                for (int i = 0; i < keys.Count; i++)
                {
                    switch (keys[i])
                    {
                        case AdvRuleKey.MeltPeaks:
                            tmpStream = new RuleStream();
                            tmpStream.Write(datas[i]);
                            tmpStream.Seek(0, System.IO.SeekOrigin.Begin);

                            int count = tmpStream.ReadInt();
                            for (int j = 0; j < count; j++)
                            {
                                tmpStream.ReadIndex(out tmpKeys, out tmpDatas);

                                MeltingPeak peak = new MeltingPeak();
                                for (int k = 0; k < tmpKeys.Count; k++)
                                {
                                    switch (tmpKeys[k])
                                    {
                                        case AdvRuleKey.Key:
                                            peak.Key = BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Tm:
                                            peak.Tm = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Rm:
                                            peak.Rm = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Width:
                                            peak.Width = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.YValue:
                                            peak.YValue = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                    }
                                }
                                _meltPeaks.Add(peak);
                            }
                            tmpStream.Close();
                            break;
                        case AdvRuleKey.Targets:
                            tmpStream = new RuleStream();
                            tmpStream.Write(datas[i]);
                            tmpStream.Seek(0, System.IO.SeekOrigin.Begin);

                            count = tmpStream.ReadInt();
                            for (int j = 0; j < count; j++)
                            {
                                tmpStream.ReadIndex(out tmpKeys, out tmpDatas);

                                Target target = new Target();
                                for (int k = 0; k < tmpKeys.Count; k++)
                                {
                                    switch (tmpKeys[k])
                                    {
                                        case AdvRuleKey.Key:
                                            target.Key = BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.TargetName:
                                            target.Name = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.TubeName:
                                            target.TubeName = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.ChannelNo:
                                            target.ChannelNo = BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Dye:
                                            target.Dye = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Ct:
                                            target.Result.Ct = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.CtMean:
                                            target.Result.CtMean = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.CtSD:
                                            target.Result.CtSD = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.CtCV:
                                            target.Result.CtCV = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Cn:
                                            target.Result.Cn = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.CnMean:
                                            target.Result.CnMean = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.CnSD:
                                            target.Result.CnSD = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.CnCV:
                                            target.Result.CnCV = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Rn:
                                            target.Result.Rn = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.r:
                                            target.Result.r = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.MeltPeaks:
                                            target.Peaks = new List<MeltingPeak>();

                                            int peakCount = BytesConverter.BytesToInt(tmpDatas[k]);
                                            for (int m = 0; m < peakCount; m++)
                                            {
                                                target.Peaks.Add(_meltPeaks[BytesConverter.BytesToInt(tmpDatas[k], 4 + m * 4)]);
                                            }
                                            break;
                                        case AdvRuleKey.RawCurve:
                                            target.Result.RawCurve = GetCurve(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.AMPCurve:
                                            target.Result.AMPCurve = GetCurve(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.RawMeltingCurve:
                                            target.Result.RawMeltingCurve = GetCurve(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PeakCurve:
                                            target.Result.PeakCurve = GetCurve(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.NormalizationPeakCurve:
                                            target.Result.NormalizationPeakCurve = GetCurve(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.DerivativeCurve:
                                            target.Result.DerivativeCurve = GetCurve(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.NormalizationCurve:
                                            target.Result.NormalizationCurve = GetCurve(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.ShiftCurve:
                                            target.Result.ShiftCurve = GetCurve(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.DifferenceCurve:
                                            target.Result.DifferenceCurve = GetCurve(tmpDatas[k]);
                                            break;
                                    }
                                }
                                _targets.Add(target);
                            }
                            tmpStream.Close();
                            break;
                        case AdvRuleKey.Wells:
                            tmpStream = new RuleStream();
                            tmpStream.Write(datas[i]);
                            tmpStream.Seek(0, System.IO.SeekOrigin.Begin);

                            count = tmpStream.ReadInt();
                            for (int j = 0; j < count; j++)
                            {
                                tmpStream.ReadIndex(out tmpKeys, out tmpDatas);

                                Tube tube = new Tube();
                                for (int k = 0; k < tmpKeys.Count; k++)
                                {
                                    switch (tmpKeys[k])
                                    {
                                        case AdvRuleKey.Key:
                                            tube.Key = BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.MultiTubeID:
                                            tube.ID = BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.TubeName:
                                            tube.Name = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Targets:
                                            tube.Targets = new List<Target>();

                                            int tubeCount = BytesConverter.BytesToInt(tmpDatas[k]);
                                            for (int m = 0; m < tubeCount; m++)
                                            {
                                                tube.Targets.Add(_targets[BytesConverter.BytesToInt(tmpDatas[k], 4 + m * 4)]);
                                            }
                                            break;
                                        case AdvRuleKey.RightAngleCurve:
                                            tube.RightAngleCurve = GetCurve(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PolarCurve:
                                            tube.PolarCurve = GetCurve(tmpDatas[k]);
                                            break;
                                    }
                                }
                                _tubes.Add(tube);
                            }
                            tmpStream.Close();
                            break;
                        case AdvRuleKey.Samples:
                            tmpStream = new RuleStream();
                            tmpStream.Write(datas[i]);
                            tmpStream.Seek(0, System.IO.SeekOrigin.Begin);

                            count = tmpStream.ReadInt();
                            for (int j = 0; j < count; j++)
                            {
                                tmpStream.ReadIndex(out tmpKeys, out tmpDatas);

                                Sample sample = new Sample();
                                for (int k = 0; k < tmpKeys.Count; k++)
                                {
                                    switch (tmpKeys[k])
                                    {
                                        case AdvRuleKey.Key:
                                            sample.Key = BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.ID:
                                            sample.ID = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Type:
                                            sample.Type = (SampleType)BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Property:
                                            sample.Property = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.MultiTubeNo:
                                            sample.MultiTubeNo = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Wells:
                                            sample.Tubes = new List<Tube>();

                                            int smapleCount = BytesConverter.BytesToInt(tmpDatas[k]);
                                            for (int m = 0; m < smapleCount; m++)
                                            {
                                                sample.Tubes.Add(_tubes[BytesConverter.BytesToInt(tmpDatas[k], 4 + m * 4)]);
                                            }
                                            break;

                                        #region 患者信息
                                        case AdvRuleKey.PID:
                                            sample.PatientInfo.ID = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PName:
                                            sample.PatientInfo.Name = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PSex:
                                            sample.PatientInfo.Sex = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PAge:
                                            sample.PatientInfo.Age = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PSpecimen:
                                            sample.PatientInfo.Specimen = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PSpecimenDate:
                                            sample.PatientInfo.SpecimenDate = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PDoctor:
                                            sample.PatientInfo.Doctor = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.POffice:
                                            sample.PatientInfo.Office = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PDiagnosis:
                                            sample.PatientInfo.Diagnosis = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PCaseID:
                                            sample.PatientInfo.CaseID = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PBedID:
                                            sample.PatientInfo.BedID = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PInPatientID:
                                            sample.PatientInfo.InPatientID = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.POutPatientID:
                                            sample.PatientInfo.OutPatientID = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PRemark:
                                            sample.PatientInfo.Remark = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        #endregion
                                    }
                                }
                                _samples.Add(sample);
                            }
                            tmpStream.Close();
                            break;
                        case AdvRuleKey.Paramter:
                            tmpStream = new RuleStream();
                            tmpStream.Write(datas[i]);
                            tmpStream.Seek(0, System.IO.SeekOrigin.Begin);

                            count = tmpStream.ReadInt();
                            for (int j = 0; j < count; j++)
                            {
                                tmpStream.ReadIndex(out tmpKeys, out tmpDatas);

                                Paramter paramter = new Paramter();
                                if (GetType() == EProjectType.Melt)
                                    paramter = new MeltParamter();
                                else if (GetType() == EProjectType.HRM)
                                    paramter = new HRMParamter();
                                else if (GetType() == EProjectType.AD)
                                    paramter = new ADParamter();

                                for (int k = 0; k < tmpKeys.Count; k++)
                                {
                                    switch (tmpKeys[k])
                                    {
                                        case AdvRuleKey.TargetName:
                                            paramter.TargetName = BytesConverter.BytesToString(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.AnalysisType:
                                            paramter.AnalysisType = (EAnalysisType)BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.BeginBaseline:
                                            paramter.BeginBaseline = BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.EndBaseline:
                                            paramter.EndBaseline = BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.AutoThreshold:
                                            paramter.AutoThreshold = BytesConverter.BytesToBool(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.Threshold:
                                            paramter.Threshold = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.OptimizationMode:
                                            paramter.OptimizationMode = (EOptionzationMode)BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.DigitalFilter:
                                            paramter.DigitalFilter = BytesConverter.BytesToBool(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.DetectionMin:
                                            paramter.DetectionMin = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.DetectionMax:
                                            paramter.DetectionMax = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.AMPGain:
                                            paramter.AMPGain = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.ParamterA:
                                            paramter.ParamterA = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.ParamterB:
                                            paramter.ParamterB = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.MinTemperature:
                                            ((MeltParamter)paramter).MinTemperature = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.MaxTemperature:
                                            ((MeltParamter)paramter).MaxTemperature = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.NoiseThreshold:
                                            ((MeltParamter)paramter).NoiseThreshold = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PeekWidthThreshold:
                                            ((MeltParamter)paramter).PeekWidthThreshold = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.PeekHightThreshold:
                                            ((MeltParamter)paramter).PeekHightThreshold = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.StartTemperatureBefore:
                                            ((HRMParamter)paramter).StartTemperatureBefore = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.EndTemperatureBefore:
                                            ((HRMParamter)paramter).EndTemperatureBefore = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.StartTemperatureAfter:
                                            ((HRMParamter)paramter).StartTemperatureAfter = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.EndTemperatureAfter:
                                            ((HRMParamter)paramter).EndTemperatureAfter = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.QualityThreshold:
                                            ((HRMParamter)paramter).QualityThreshold = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.TemperatureShiftThreshold:
                                            ((HRMParamter)paramter).TemperatureShiftThreshold = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.TypeMethod:
                                            ((HRMParamter)paramter).TypeMethod = (EHRMTypeMethod)BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.ClassificationMethod:
                                            ((HRMParamter)paramter).ClassificationMethod = (EHRMClassificationMethod)BytesConverter.BytesToInt(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.ClassThreshold:
                                            ((HRMParamter)paramter).ClassThreshold = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.ADQualityThreshold:
                                            ((ADParamter)paramter).QualityThreshold = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.ADGainRatio:
                                            ((ADParamter)paramter).GainRatio = BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                        case AdvRuleKey.ADTypeMethod:
                                            ((ADParamter)paramter).TypeMethod = (EADTypeMethod)BytesConverter.BytesToDouble(tmpDatas[k]);
                                            break;
                                    }
                                }
                                _paramters.Add(paramter);
                            }                            
                            break;
                    }
                }
                #endregion
            }
            else
            {
                stream.Seek(-4, SeekOrigin.Current);
                #region 旧逻辑
                while (stream.Position != stream.Length && (key = stream.ReadKey()) != AdvRuleKey.End)
                {
                    if (key == AdvRuleKey.MeltPeaks)
                    {
                        int count = stream.ReadInt();

                        for (int i = 0; i < count; i++)
                        {
                            if ((key = (AdvRuleKey)stream.ReadInt()) == AdvRuleKey.MeltPeak)
                            {
                                MeltingPeak peak = new MeltingPeak();
                                #region 读取数据
                                while ((key = (AdvRuleKey)stream.ReadInt()) != AdvRuleKey.End)
                                {
                                    if (key == AdvRuleKey.Key)
                                    {
                                        peak.Key = stream.ReadInt();
                                    }
                                    else if (key == AdvRuleKey.Tm)
                                    {
                                        peak.Tm = stream.ReadDouble();
                                    }
                                    else if (key == AdvRuleKey.Rm)
                                    {
                                        peak.Rm = stream.ReadDouble();
                                    }
                                }
                                #endregion
                                _meltPeaks.Add(peak);
                            }
                            else
                                return false;
                        }
                        //读取结束标志，如果不是结束标志，说明数据块有错误。
                        if ((key = (AdvRuleKey)stream.ReadInt()) != AdvRuleKey.End)
                            return false;
                    }
                    else if (key == AdvRuleKey.Targets)
                    {
                        int count = stream.ReadInt();
                        for (int i = 0; i < count; i++)
                        {
                            if ((key = (AdvRuleKey)stream.ReadInt()) == AdvRuleKey.Target)
                            {
                                Target target = new Target();
                                #region 读取数据
                                while ((key = (AdvRuleKey)stream.ReadInt()) != AdvRuleKey.End)
                                {
                                    if (key == AdvRuleKey.Key)
                                    {
                                        target.Key = stream.ReadInt();
                                    }
                                    else if (key == AdvRuleKey.TargetName)
                                    {
                                        target.Name = stream.ReadString();
                                    }
                                    else if (key == AdvRuleKey.TubeName)
                                    {
                                        target.TubeName = stream.ReadString();
                                    }
                                    else if (key == AdvRuleKey.ChannelNo)
                                    {
                                        target.ChannelNo = stream.ReadInt();
                                    }
                                    else if (key == AdvRuleKey.Dye)
                                    {
                                        target.Dye = stream.ReadString();
                                    }
                                    else if (key == AdvRuleKey.Ct)
                                    {
                                        target.Result.Ct = stream.ReadDouble();
                                    }
                                    else if (key == AdvRuleKey.CtMean)
                                    {
                                        target.Result.CtMean = stream.ReadDouble();
                                    }
                                    else if (key == AdvRuleKey.CtSD)
                                    {
                                        target.Result.CtSD = stream.ReadDouble();
                                    }
                                    else if (key == AdvRuleKey.CtCV)
                                    {
                                        target.Result.CtCV = stream.ReadDouble();
                                    }
                                    else if (key == AdvRuleKey.Cn)
                                    {
                                        target.Result.Cn = stream.ReadDouble();
                                    }
                                    else if (key == AdvRuleKey.CnMean)
                                    {
                                        target.Result.CnMean = stream.ReadDouble();
                                    }
                                    else if (key == AdvRuleKey.CnSD)
                                    {
                                        target.Result.CnSD = stream.ReadDouble();
                                    }
                                    else if (key == AdvRuleKey.CnCV)
                                    {
                                        target.Result.CnCV = stream.ReadDouble();
                                    }
                                    else if (key == AdvRuleKey.Rn)
                                    {
                                        target.Result.Rn = stream.ReadDouble();
                                    }
                                    else if (key == AdvRuleKey.r)
                                    {
                                        target.Result.r = stream.ReadDouble();
                                    }
                                    else if (key == AdvRuleKey.MeltPeaks)
                                    {
                                        target.Peaks = new List<MeltingPeak>();

                                        int peakCount = stream.ReadInt();
                                        for (int j = 0; j < peakCount; j++)
                                        {
                                            target.Peaks.Add(_meltPeaks[stream.ReadInt()]);
                                        }
                                    }
                                }
                                #endregion
                                _targets.Add(target);
                            }
                            else
                                return false;
                        }
                        //读取结束标志，如果不是结束标志，说明数据块有错误。
                        if ((key = (AdvRuleKey)stream.ReadInt()) != AdvRuleKey.End)
                            return false;
                    }
                    else if (key == AdvRuleKey.Wells)
                    {
                        int count = stream.ReadInt();
                        for (int i = 0; i < count; i++)
                        {
                            if ((key = (AdvRuleKey)stream.ReadInt()) == AdvRuleKey.Well)
                            {
                                Tube tube = new Tube();
                                #region 读取数据
                                while ((key = (AdvRuleKey)stream.ReadInt()) != AdvRuleKey.End)
                                {
                                    if (key == AdvRuleKey.Key)
                                    {
                                        tube.Key = stream.ReadInt();
                                    }
                                    else if (key == AdvRuleKey.MultiTubeID)
                                    {
                                        tube.ID = stream.ReadInt();
                                    }
                                    else if (key == AdvRuleKey.TubeName)
                                    {
                                        tube.Name = stream.ReadString();
                                    }
                                    else if (key == AdvRuleKey.Targets)
                                    {
                                        tube.Targets = new List<Target>();

                                        int tubeCount = stream.ReadInt();
                                        for (int j = 0; j < tubeCount; j++)
                                        {
                                            tube.Targets.Add(_targets[stream.ReadInt()]);
                                        }
                                    }
                                }
                                #endregion
                                _tubes.Add(tube);
                            }
                            else
                                return false;
                        }
                        //读取结束标志，如果不是结束标志，说明数据块有错误。
                        if ((key = (AdvRuleKey)stream.ReadInt()) != AdvRuleKey.End)
                            return false;
                    }
                    else if (key == AdvRuleKey.Samples)
                    {
                        int count = stream.ReadInt();
                        for (int i = 0; i < count; i++)
                        {
                            if ((key = (AdvRuleKey)stream.ReadInt()) == AdvRuleKey.Sample)
                            {
                                Sample sample = new Sample();
                                #region 读取数据
                                while ((key = (AdvRuleKey)stream.ReadInt()) != AdvRuleKey.End)
                                {
                                    if (key == AdvRuleKey.Key)
                                    {
                                        sample.Key = stream.ReadInt();
                                    }
                                    else if (key == AdvRuleKey.ID)
                                    {
                                        sample.ID = stream.ReadString();
                                    }
                                    else if (key == AdvRuleKey.Type)
                                    {
                                        sample.Type = (SampleType)stream.ReadInt();
                                    }
                                    else if (key == AdvRuleKey.Property)
                                    {
                                        sample.Property = stream.ReadString();
                                    }
                                    else if (key == AdvRuleKey.MultiTubeNo)
                                    {
                                        sample.MultiTubeNo = stream.ReadString();
                                    }
                                    else if (key == AdvRuleKey.Wells)
                                    {
                                        sample.Tubes = new List<Tube>();

                                        int smapleCount = stream.ReadInt();
                                        for (int j = 0; j < smapleCount; j++)
                                        {
                                            sample.Tubes.Add(_tubes[stream.ReadInt()]);
                                        }
                                    }
                                }
                                #endregion
                                _samples.Add(sample);
                            }
                            else
                                return false;
                        }
                        //读取结束标志，如果不是结束标志，说明数据块有错误。
                        if ((key = (AdvRuleKey)stream.ReadInt()) != AdvRuleKey.End)
                            return false;
                    }
                }
                #endregion
            }
            return true;
        }
        #endregion

        List<Dot> GetCurve(byte[] data)
        {
            List<Dot> list = new List<Dot>();

            if (data != null)
            {
                int count = BytesConverter.BytesToInt(data);

                for (int i = 0; i < count; i++)
                {
                    list.Add(new Dot() { X = BytesConverter.BytesToDouble(data, 4 + 8 * i * 2), Y = BytesConverter.BytesToDouble(data, 4 + 8 * i * 2 + 8) });
                }
            }

            return list;
        }
        byte[] GetByte(List<Dot> curve)
        {
            List<byte> list = new List<byte>();

            list.AddRange(BytesConverter.GetBytes(curve.Count));
            foreach (Dot dot in curve)
            {
                list.AddRange(BytesConverter.GetBytes(dot.X));
                list.AddRange(BytesConverter.GetBytes(dot.Y));
            }

            return list.ToArray();
        }
    }
}
